<template>
    <div class="main_box">
        <div class="main_row">
            <p>父组件传入的user, name:{{ props.user.name }}</p>
            <el-button @click="handleUpEmits">修改user</el-button>
            <el-button @click="handleResetEmits">重置user</el-button>
        </div>
    </div>
</template>

<!-- script setup写法 -->
<script setup lang="ts">
// defineProps, defineEmits, defineExpose, withDefaults, defineOptions无需导入
import { ref } from 'vue';

defineOptions({
    name: 'TsDemo3_son'
});

export interface UserProps {
    name: string;
    age: number;
    sex: '男' | '女';
    hobby: string[];
}

// 1.没有默认值
const props = defineProps<{
    id?: number; // 非必传
    user: UserProps; // 必传
}>();

// 2.有默认值,需要使用withDefaults,第一个参数是props,第二个参数是默认值
// const props = withDefaults(
//     defineProps<{
//         id?: number;
//         user: UserProps;
//     }>(),
//     {
//         id: 0,
//         user: () => ({
//             name: '张三',
//             age: 18,
//             sex: '男',
//             hobby: ['篮球', '足球']
//         })
//     }
// );

// emit写法1：无类型约束
// const emit = defineEmits(['updateUser', 'resetUser']);

// emit写法2：有类型约束
// const emit = defineEmits<{
//     (e: 'updateUser', user: { name: string }): void;
//     (e: 'resetUser'): void;
// }>();

// emit写法3：有类型约束(需要vue3.3+)
const emit = defineEmits<{
    updateUser: [user: { name: string }];
    resetUser: [];
}>();

const handleUpEmits = () => {
    emit('updateUser', { name: '李四' });
};

const handleResetEmits = () => {
    emit('resetUser');
};

// 暴露给父组件
const sonRef = ref<number>(1);
const sonFn = <T,>(params: T): T => {
    return params;
};

defineExpose({
    sonRef,
    sonFn
});
</script>

<!-- setup()写法 -->
<!-- <script lang="ts">
import { defineComponent, ref } from 'vue';

interface UserProps {
    name: string;
    age: number;
    sex: '男' | '女';
    hobby: string[];
}

export default defineComponent({
    name: 'TsDemo3_son',
    props: {
        id: {
            type: Number,
            default: undefined
        },
        user: {
            type: Object as () => UserProps,
            required: true,
            default: () => ({
                name: '张三',
                age: 18,
                sex: '男',
                hobby: ['篮球', '足球']
            })
        }
    },
    // 写法1: 无类型约束
    // emits: ['updateUser', 'resetUser'],
    // 写法2: 有类型约束
    emits: {
        updateUser: (payload: { name: string }) => true,
        resetUser: () => true
    },

    setup(props, { emit }) {
        const sonRef = ref<number>(1);
        const sonFn = <T,>(params: T): T => params;

        const handleUpEmits = () => {
            emit('updateUser', { name: '李四' });
        };

        const handleResetEmits = () => {
            emit('resetUser');
        };

        return {
            props,
            sonRef,
            sonFn,
            handleUpEmits,
            handleResetEmits
        };
    }
});
</script> -->
